<template>
  <div>
    <h1>Vue 3 响应式基础学习</h1>
    
    <!-- 1. ref() 基本响应式引用 -->
    <div class="reactivity-section">
      <h2 class="section-title">1. ref() - 响应式的魔法盒子</h2>
      <div class="demo-box">
        <p>想象 ref 是一个神奇的盒子，它能记住里面装的东西，并且当东西变化时通知所有人！</p>
        <p>当前魔法数字：<span class="value-display">{{ magicNumber }}</span></p>
        <div class="button-group">
          <button @click="incrementMagicNumber">魔法 +1</button>
          <button @click="doubleMagicNumber">魔法 ×2</button>
        </div>
        <p>你已经施展了 {{ castCount }} 次魔法！</p>
      </div>
      <div class="explanation">
        <p><strong>什么是 ref？</strong></p>
        <p>ref() 函数可以将普通值转换为响应式引用。它会返回一个包含 <code>value</code> 属性的对象。在模板中使用时，Vue 会自动解包（不需要写 .value），但在脚本中需要使用 .value 访问或修改值。</p>
      </div>
    </div>

    <!-- 2. reactive() 响应式对象 -->
    <div class="reactivity-section">
      <h2 class="section-title">2. reactive() - 响应式物体</h2>
      <div class="demo-box">
        <p>现在我们来创建一个会动的 <strong>响应式宠物</strong>！</p>
        <p>宠物名称：<span class="value-display">{{ pet.name }}</span></p>
        <p>宠物年龄：<span class="value-display">{{ pet.age }}</span> 岁</p>
        <p>宠物心情：<span class="value-display">{{ pet.mood }}</span></p>
        <div class="button-group">
          <button @click="pet.age++">庆祝生日</button>
          <button @click="changePetMood">改变心情</button>
          <button @click="changePetName">换个名字</button>
        </div>
      </div>
      <div class="explanation">
        <p><strong>什么是 reactive？</strong></p>
        <p>reactive() 函数用于创建响应式对象。与 ref 不同，它直接返回一个响应式代理，不需要通过 .value 访问。但请注意，reactive 只能用于对象类型，不能用于基本类型（数字、字符串等）。</p>
      </div>
    </div>

    <!-- 3. computed() 计算属性 -->
    <div class="reactivity-section">
      <h2 class="section-title">3. computed() - 智能计算器</h2>
      <div class="demo-box">
        <p>让我们来做一个 <strong>水果计算器</strong>！</p>
        <p>苹果数量：<button @click="apples--">-</button> <span class="value-display">{{ apples }}</span> <button @click="apples++">+</button></p>
        <p>香蕉数量：<button @click="bananas--">-</button> <span class="value-display">{{ bananas }}</span> <button @click="bananas++">+</button></p>
        <p>🍎 苹果总价：<span class="value-display">{{ appleTotal }} 元</span></p>
        <p>🍌 香蕉总价：<span class="value-display">{{ bananaTotal }} 元</span></p>
        <p style="font-weight: bold;">💰 总计：<span class="value-display">{{ totalPrice }} 元</span></p>
      </div>
      <div class="explanation">
        <p><strong>什么是 computed？</strong></p>
        <p>computed() 函数用于创建计算属性。计算属性会根据依赖的响应式数据自动更新，并且有缓存功能，只有当依赖变化时才会重新计算。这比在模板中直接写复杂逻辑更高效、更易维护。</p>
      </div>
    </div>

    <!-- 4. watch() 和 watchEffect() 侦听器 -->
    <div class="reactivity-section">
      <h2 class="section-title">4. watch() & watchEffect() - 数据侦探</h2>
      <div class="demo-box">
        <p>欢迎来到 <strong>数据侦探</strong> 游戏！</p>
        <p>输入一个秘密数字：<input v-model="secretNumber" type="number" placeholder="输入数字" /></p>
        <p>侦探报告 (watch)：<span class="value-display">{{ watchMessage }}</span></p>
        <p>自动侦探 (watchEffect)：<span class="value-display">{{ effectMessage }}</span></p>
        <p>上次更新时间：<span class="value-display">{{ lastUpdateTime }}</span></p>
      </div>
      <div class="explanation">
        <p><strong>什么是 watch 和 watchEffect？</strong></p>
        <p><code>watch()</code> 允许你监听特定的响应式数据变化，并执行回调函数。它需要明确指定要监听的数据源。</p>
        <p><code>watchEffect()</code> 会自动跟踪回调函数中使用的所有响应式数据，当这些数据变化时重新执行回调。它更简洁，但不太精确控制监听的数据源。</p>
      </div>
    </div>

    <!-- 5. toRefs() 响应式转换 -->
    <div class="reactivity-section">
      <h2 class="section-title">5. toRefs() - 响应式拆分器</h2>
      <div class="demo-box">
        <p>现在我们来拆分一个 <strong>响应式游戏角色</strong>！</p>
        <p>角色名称：<span class="value-display">{{ player.name }}</span></p>
        <p>角色等级：<span class="value-display">{{ player.level }}</span></p>
        <p>角色生命值：<span class="value-display">{{ player.hp }}</span></p>
        <div class="button-group">
          <button @click="levelUp">升级</button>
          <button @click="takeDamage">受伤</button>
          <button @click="heal">治疗</button>
        </div>
      </div>
      <div class="explanation">
        <p><strong>什么是 toRefs？</strong></p>
        <p><code>toRefs()</code> 函数可以将响应式对象的每个属性转换为单独的 ref。这在组件间传递数据时非常有用，特别是当你想解构响应式对象但又不想失去响应性时。</p>
      </div>
    </div>

    <!-- 有趣的总结 -->
    <div class="reactivity-section">
      <h2 class="section-title">🎉 响应式魔法总结</h2>
      <div class="demo-box">
        <ul style="list-style: none; padding: 0;">
          <li>✨ <code>ref()</code> - 给基本类型（数字、字符串等）施加响应式魔法</li>
          <li>🐶 <code>reactive()</code> - 让对象变得活泼好动</li>
          <li>🧮 <code>computed()</code> - 聪明的计算器，会缓存结果</li>
          <li>🔍 <code>watch()</code> - 专注的侦探，只跟踪你指定的线索</li>
          <li>🕵️ <code>watchEffect()</code> - 自动侦探，发现所有相关线索</li>
          <li>✂️ <code>toRefs()</code> - 响应式拆分器，把对象拆分成独立的 ref</li>
        </ul>
        <p style="margin-top: 20px;">恭喜你掌握了 Vue 3 响应式的基本魔法！继续练习，你会成为响应式大师的！</p>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, watchEffect, toRefs, onMounted } from 'vue'

// 1. ref() 演示
const magicNumber = ref(42)
const castCount = ref(0)

function incrementMagicNumber() {
  magicNumber.value++
  castCount.value++
}

function doubleMagicNumber() {
  magicNumber.value *= 2
  castCount.value++
}

// 2. reactive() 演示
const pet = reactive({
  name: '小汪',
  age: 2,
  mood: '开心'
})

const moods = ['开心', '兴奋', '平静', '疲惫', '生气']
const petNames = ['小汪', '喵喵', '球球', '贝贝', '可可']

function changePetMood() {
  const randomIndex = Math.floor(Math.random() * moods.length)
  pet.mood = moods[randomIndex]
}

function changePetName() {
  const randomIndex = Math.floor(Math.random() * petNames.length)
  pet.name = petNames[randomIndex]
}

// 3. computed() 演示
const apples = ref(0)
const bananas = ref(0)
const applePrice = 5 // 苹果单价
const bananaPrice = 3 // 香蕉单价

const appleTotal = computed(() => apples.value * applePrice)
const bananaTotal = computed(() => bananas.value * bananaPrice)
const totalPrice = computed(() => appleTotal.value + bananaTotal.value)

// 4. watch() 和 watchEffect() 演示
const secretNumber = ref(0)
const watchMessage = ref('等待输入...')
const effectMessage = ref('准备就绪')
const lastUpdateTime = ref('')

watch(secretNumber, (newValue, oldValue) => {
  if (newValue > 100) {
    watchMessage.value = `🚨 秘密数字 ${newValue} 太大了！`
  } else if (newValue < 0) {
    watchMessage.value = `❓ 秘密数字 ${newValue} 是负数！`
  } else {
    watchMessage.value = `✅ 秘密数字从 ${oldValue} 变为 ${newValue}`
  }
}, { immediate: true })

watchEffect(() => {
  // 这个函数会自动跟踪 secretNumber 的变化
  effectMessage.value = `我发现你输入了 ${secretNumber.value}`
  lastUpdateTime.value = new Date().toLocaleTimeString()
})

// 5. toRefs() 演示
const playerData = reactive({
  name: '勇敢的骑士',
  level: 1,
  hp: 100
})

// 使用 toRefs 拆分响应式对象
const player = toRefs(playerData)

function levelUp() {
  playerData.level++
  playerData.hp = 100 // 升级后满血
}

function takeDamage() {
  playerData.hp = Math.max(0, playerData.hp - 20)
}

function heal() {
  playerData.hp = Math.min(100, playerData.hp + 30)
}

// 组件挂载时的欢迎信息
onMounted(() => {
  console.log('🎉 Vue 3 响应式基础学习开始！')
  console.log('💡 尝试点击各种按钮来体验响应式魔法！')
})
</script>

<style scoped>
input {
  padding: 8px;
  border-radius: 4px;
  border: 1px solid #ccc;
  margin: 0 10px;
  background: rgba(255, 255, 255, 0.1);
  color: inherit;
  font-size: 1em;
}

@media (prefers-color-scheme: light) {
  input {
    background: #fff;
    color: #213547;
  }
}
</style>